package com.huanledoudizhu.service.impl;

import com.huanledoudizhu.controller.result.ResponseResult;
import com.huanledoudizhu.controller.result.ResultCode;
import com.huanledoudizhu.entity.File;
import com.huanledoudizhu.entity.FileShare;
import com.huanledoudizhu.entity.bean.CompactAlgorithm;
import com.huanledoudizhu.mapper.FileShareMapper;
import com.huanledoudizhu.service.FileService;
import com.huanledoudizhu.service.FileShareService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huanledoudizhu
 * @since 2022-11-21
 */
@Service
public class FileShareServiceImpl extends ServiceImpl<FileShareMapper, FileShare> implements FileShareService {
    @Autowired
    FileService fileService;
    @Autowired
    CompactAlgorithm compactAlgorithm;
    @Autowired
    FileShareMapper fileShareMapper;


    //目前bug：如果删除文件到回收站。分享时文件会有回收站的文件
    public ResponseResult generateLink(int id, Date expirationTime) throws IOException {
        File operatedFile = fileService.getById(id);

        String uuid = (UUID.randomUUID().toString().split("-"))[0];
        FileShare fileShare = new FileShare();
        fileShare.setFileId(id);
        fileShare.setShareMd5(operatedFile.getFileMd5());
        fileShare.setShareUuid(uuid);

        //date转localdatetime
        LocalDateTime localDateTime = LocalDateTime.ofInstant(expirationTime.toInstant(), ZoneId.systemDefault());

        fileShare.setExpirationTime(localDateTime);



        //压缩文件夹--------------------------
        if (operatedFile.getIsDir()==1){
            String basepath = System.getProperty("user.dir");//获取项目路径
            String userPath = basepath + "\\src\\main\\resources\\share";

            //待压缩的目录
            String sourceFile = operatedFile.getFileLocation();
            java.io.File fileToZip = new java.io.File(sourceFile);
            //压缩以后得到的efi文件路径efi.zip
            String p = userPath+"\\"+ new Date().getTime()+id;
            new java.io.File(p).mkdirs();
            FileOutputStream fos = new FileOutputStream(p + "\\" + fileToZip.getName() +".zip");
            ZipOutputStream zipOut = new ZipOutputStream(fos);
            fileShare.setShareLocation(p);
            zipFile(fileToZip, fileToZip.getName(), zipOut);
            zipOut.close();
            fos.close();
        }
        //压缩文件夹--------------------------

        this.save(fileShare);
        return new ResponseResult(ResultCode.SUCESS,fileShare);
    }

    public ResponseResult linkDownload(String uuid, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest) throws IOException {
        FileShare fileShare = fileShareMapper.getByUUID(uuid);
        if (fileShare==null){
            return new ResponseResult(ResultCode.PARAM_IS_INVALID);
        }
        File file = fileService.getById(fileShare.getFileId());
        String path = "";
        String fileName = "";
        String extension = "";
        if (file.getIsDir()==1){
            path = fileShare.getShareLocation();;
            fileName = file.getFileName()+".zip";
        }else {
            path = file.getFileLocation();
            extension = file.getFileExtension();
            fileName = file.getFileName()+"."+extension;
        }
        if (path!=null||!path.equals("")){
            FileInputStream fileInputStream = new FileInputStream(new java.io.File(path,fileName));
            httpServletResponse.setContentType(httpServletRequest.getSession().getServletContext().getMimeType(extension));//获取文件的mimetype
            httpServletResponse.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
            ServletOutputStream os = httpServletResponse.getOutputStream();
            FileCopyUtils.copy(fileInputStream,os);
            return new ResponseResult(ResultCode.SUCESS,file);
        }
        return new ResponseResult(ResultCode.FAILURE);
    }

    private static void zipFile(java.io.File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
        if (fileToZip.isHidden()) {
            return;
        }
        if (fileToZip.isDirectory()) {
            if (fileName.endsWith("/")) {
                zipOut.putNextEntry(new ZipEntry(fileName));
                zipOut.closeEntry();
            } else {
                zipOut.putNextEntry(new ZipEntry(fileName + "\\"));
                zipOut.closeEntry();
            }
            java.io.File[] children = fileToZip.listFiles();
            for (java.io.File childFile : children) {
                zipFile(childFile, fileName + "\\" + childFile.getName(), zipOut);
            }
            return;
        }
        FileInputStream fis = new FileInputStream(fileToZip);
        ZipEntry zipEntry = new ZipEntry(fileName);
        zipOut.putNextEntry(zipEntry);
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zipOut.write(bytes, 0, length);
        }
        fis.close();
    }

}
